package Day_0226.TemplateMethodPattern;

/**
 * @author zxc
 * @date 2023/02/26 23:01
 **/
public class TemplateMethodPattern {
    public static void main(String[] args) {
        /**
         * 谈一谈对于模板方法模式的理解
         * ===》
         * 1.模板方法的概念
         * ===》
         * 模板方法模式：
         * （1）定义一个操作中的算法骨架（父类），而将一些步骤延迟到子类中。
         * （2）模板方法使得子类可以不改变一个算法的结构，来重定义该算法。
         *
         * 2.模板方法的使用时机
         * ===》
         * 实现一些操作时，整体步骤很固定，但是呢。就是其中一小部分需要改变，
         * 这时候可以使用模板方法模式，将容易变的部分抽象出来，供子类实现。
         *
         * 3.实际开发中应用场景哪里用到了模板方法
         * ===》
         * 例如：数据库访问的封装、Junit单元测试、servlet中关于doGet/doPost方法的调用等等
         *
         * 4.现实生活中的模板方法
         * ===》
         * 例如：
         * 去餐厅吃饭，餐厅给我们提供了一个模板就是：看菜单，点菜，吃饭，付款，走人
         * （这里 “点菜和付款” 是不确定的由子类来完成的，其他的则是一个模板。）
         *
         * ===》
         * 总结 ：
         * （1）即，模板方法模式适用于 整体流程较为固定 && 尤其仅有其中部分内容需要进行修改;
         * （2）定义一个 abstract的模板方法 && 同时让子类去继承该模板类，实现模板类中所定义的abstract方法;
         *  ===》即，在模板类的子类中所定义的abstract方法，是需要各个子类去具体实现的，各个子类之间都是不尽相同的;
         * （3）模板类 + 模板类对象 = new 实现模板类的子类;
         * （4）调用模板类中的方法 && 继承模板类的子类，能够实现一个专属于某个子类的模板方法;
         *
         */
    }
}
// 模板方法（定义一个抽象类，提供给其他子类来进行继承;）
abstract class RestaurantTemplate {
    // 1.看菜单
    public void menu() {
        System.out.println("看菜单");
    }
    // 2.点菜业务
    abstract void spotMenu();
    // 3.吃饭业务
    public void havingDinner(){ System.out.println("吃饭"); }
    // 3.付款业务
    abstract void payment();
    // 3.走人
    public void GoR() { System.out.println("走人"); }

    // 模板方法的通用结构
    public void process(){
        menu();
        spotMenu();
        havingDinner();
        payment();
        GoR();
    }
}
// 实现该模板方法的子类1
class RestaurantGinsengImpl extends RestaurantTemplate {
    void spotMenu() {
        System.out.println("人参");
    }
    void payment() {
        System.out.println("5快");
    }
}
// 实现该模板方法的子类2
class RestaurantLobsterImpl extends RestaurantTemplate {
    void spotMenu() {
        System.out.println("龙虾");
    }
    void payment() {
        System.out.println("50块");
    }
}
class Client {
    public static void main(String[] args) {
        //调用第一个模板实例
        RestaurantTemplate restaurantTemplate = new RestaurantGinsengImpl();
        restaurantTemplate.process();
        System.out.println("==========================");
        RestaurantTemplate restaurantTemplate1 = new RestaurantLobsterImpl();
        restaurantTemplate1.process();
    }
}

